﻿#ifndef ThreadPOSIX_h__2013_10_19__21_25
#define ThreadPOSIX_h__2013_10_19__21_25

#include "df.h"

namespace df
{
#include <pthread.h>
	class Thread
	{

	private:
		pthread_t thread_ = 0;

	public:
		Thread()
		{

		}
		//*******************************************
		// Summary : 阻塞等待线程执行完成
		// Parameter - DWORD time : posix不支持等待超时值
		// Returns - bool : 成功与否(未超时)
		//*******************************************
		bool Wait(DWORD time = 0, df::ErrWrap err = nullptr)
		{
			void *thread_result;
			int res = pthread_join(thread_, &thread_result);
			if (res != 0)
			{
				DF_LASTERR(err, tcc_("pthread_join failed!"));
				return false;
			}
			return true;
		}


		template<class LambdaType>
		inline bool Run(LambdaType lam, df::ErrWrap err = nullptr)
		{
			LambdaType * lp = new LambdaType(lam);
			int res = pthread_create(&thread_, NULL, RunThread<LambdaType>, (void *)lp);
			if (res != 0)
			{
				delete lp;
				DF_LASTERR(err, tcc_("pthread_create failed!"));
				return false;
			}

			return true;
		}

		template<class LambdaType>
		inline static bool Start(LambdaType lam, df::ErrWrap err = nullptr)
		{
			LambdaType * lp = new LambdaType(lam);
			pthread_t a_thread;
			pthread_attr_t attr;
			pthread_attr_init(&attr);
			pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
			int res = pthread_create(&a_thread, NULL, RunThread<LambdaType>, (void *)lp);
			pthread_attr_destroy(&attr);
			if (res != 0)
			{
				delete lp;
				DF_LASTERR(err, tcc_("pthread_create failed!"));
				return false;
			}
			//pthread_detach(pthread_self());
			return true;
		}

	private:
		template<class LambdaType>
		static void * RunThread(void *tp)
		{
			LambdaType * lp = (LambdaType *)tp;

			try
			{
				(*lp)();

			}DF_CATCH_ALL_EXCEPTION();

			delete lp;

			//::pthread_exit(0);
			return nullptr;
		}

		DF_DISABLE_COPY_ASSIGN(Thread);
	};


}

#endif // ThreadPOSIX_h__2013_10_19__21_25
